package javase.jmx.monitoring;

import java.lang.management.ManagementFactory;

import javase.jmx.mbeans.Hello;

import javax.management.MBeanServer;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import javax.management.monitor.CounterMonitor;

public class CounterMonitorAgent {
	private static final String ATTRIBUTE_NAME = "CacheSize";
	private static final String MBEANS_NAME = "javase.jmx.mbeans:type=Hello";
	private static final String MONITOR_NAME = "javase.jmx.monitor:type=CounterMonitor";

	public static void main(String[] args) throws Exception {
		CounterMonitor counterMonitor = getInitializedMonitor();
		counterMonitor.start();
		startIncrementation();
		Thread.sleep(20000);
		counterMonitor.stop();
	}

	private static void startIncrementation() {
		Thread incrementor = new Thread(new MBeanPrppertyIncremetHelper(MBEANS_NAME, ATTRIBUTE_NAME));
		incrementor.setDaemon(true);
		incrementor.start();
	}

	private static CounterMonitor getInitializedMonitor() throws Exception {
		CounterMonitor counterMonitor = getConfiguredMonitor();
		
		addNotificationListener(counterMonitor);
		
		registerMonitor(counterMonitor);
		return counterMonitor;
	}

	private static void registerMonitor(CounterMonitor counterMonitor) throws Exception {
		MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
		ObjectName name = new ObjectName(MONITOR_NAME);
		mBeanServer.registerMBean(counterMonitor, name);
	}

	private static void addNotificationListener(CounterMonitor counterMonitor) {
		NotificationListener listener = new MonitorNotificationListener();
		counterMonitor.addNotificationListener(listener, null, null);
	}

	private static CounterMonitor getConfiguredMonitor() throws Exception {
		CounterMonitor counterMonitor = new CounterMonitor();
		counterMonitor.addObservedObject(getRegisteredMBeanObjectName(MBEANS_NAME));
		counterMonitor.setObservedAttribute(ATTRIBUTE_NAME);
		counterMonitor.setGranularityPeriod(1000);
		counterMonitor.setInitThreshold(210);
		counterMonitor.setNotify(true); // you should explicitly set this flag
		counterMonitor.setOffset(5);
		return counterMonitor;
	}

	private static ObjectName getRegisteredMBeanObjectName(String nameString) throws Exception {
		MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
		ObjectName objectName = new ObjectName(nameString); 
		
		if (!mBeanServer.isRegistered(objectName)) {
			Hello mbean = new Hello(); 
			mBeanServer.registerMBean(mbean, objectName);
		}
		return objectName;
	}
}
